#include <iostream>
#include <string.h>
#include "hpdf.h"
#include <stdio.h>
#include <wchar.h>
#include <codecvt>


const int CHAR_PER_PAGE = 200;
const int CHAR_PER_LINE = 10;
const int FONT_SIZE = 20;
const char* FONT_FILE_NAME = "Arial_Unicode_MS.ttf";

inline
std::string codepoint_to_utf8(char32_t cp)
{
    char utf8[4];
    char* end_of_utf8;

    char32_t const* from = &cp;

    std::mbstate_t mbs;
    std::codecvt_utf8<char32_t> ccv;

    if (ccv.out(mbs, from, from + 1, from, utf8, utf8 + 4, end_of_utf8))
        throw std::runtime_error("bad conversion");

    return { utf8, end_of_utf8 };
}


int main()
{
    auto pdf= HPDF_New(NULL, NULL);
    HPDF_SetCompressionMode(pdf, HPDF_COMP_ALL);
    HPDF_UseUTFEncodings(pdf);
    HPDF_SetCurrentEncoder(pdf, "UTF-8");

    auto font_name = HPDF_LoadTTFontFromFile(pdf, FONT_FILE_NAME, HPDF_TRUE);
    auto font = HPDF_GetFont(pdf, font_name, "UTF-8");
    auto page = HPDF_AddPage(pdf);
    HPDF_Page_SetFontAndSize(page, font, FONT_SIZE);

    const auto char_width = HPDF_Page_TextWidth(page, "A");
    const auto page_width = HPDF_Page_GetWidth(page);
    const auto page_height = HPDF_Page_GetHeight(page);
    const auto dy = (page_height)/ ((CHAR_PER_PAGE / CHAR_PER_LINE) );
    const auto dx = (page_width  - ((CHAR_PER_LINE) * char_width)) / (CHAR_PER_LINE -1) ;
    HPDF_Page_BeginText(page);
    HPDF_Page_MoveTextPos(page, page_width - (2 * char_width), page_height);
    unsigned int count = 0;
    auto fontdef = HPDF_GetTTFontDefFromFile(pdf, "Arial_Unicode_MS.ttf", 1);
    for (unsigned int codepoint = 0x0000; codepoint < 0xFFFF; codepoint++)
    {
        if (HPDF_TTFontDef_GetGlyphid(fontdef, codepoint) == 0)
            continue;
        if (count % CHAR_PER_LINE == 0)
        {
            HPDF_Page_MoveTextPos(page, -dx * (CHAR_PER_LINE), -dy);
        }

        HPDF_Page_ShowText(page, codepoint_to_utf8(codepoint).c_str());
        HPDF_Page_MoveTextPos(page, dx, 0);
        ++count;
        if (count % (CHAR_PER_PAGE) == 0)
        {
            page = HPDF_AddPage(pdf);
            HPDF_Page_BeginText(page);
            HPDF_Page_SetFontAndSize(page, font, FONT_SIZE);
            HPDF_Page_MoveTextPos(page, page_width - (2 * char_width), page_height);

        }
    }
    
    HPDF_Page_EndText(page);
    HPDF_SaveToFile(pdf, "out.pdf");
    HPDF_Free(pdf);

	return 0;
}